home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
gnu
/
ghspt261.gz
/
ghspt261
/
gs261
/
gs_fonts.ps
< prev
next >
Wrap
Text File
|
1993-05-27
|
17KB
|
538 lines
% Copyright (C) 1990, 1992, 1993 Aladdin Enterprises. All rights reserved.
%
% This file is part of Ghostscript.
%
% Ghostscript is distributed in the hope that it will be useful, but
% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
% to anyone for the consequences of using it or for whether it serves any
% particular purpose or works at all, unless he says so in writing. Refer
% to the Ghostscript General Public License for full details.
%
% Everyone is granted permission to copy, modify and redistribute
% Ghostscript, but only under the conditions described in the Ghostscript
% General Public License. A copy of this license is supposed to have been
% given to you along with Ghostscript so you can know your rights and
% responsibilities. It should be in a file named COPYING. Among other
% things, the copyright notice and this notice must be preserved on all
% copies.
% Font initialization for Ghostscript.
% The standard representation for PostScript compatible fonts is described
% in the book "Adobe Type 1 Font Format", published by Adobe Systems Inc.
% We don't attempt to document this representation here.
% Ghostscript uses Type 1 fonts, except that the external form doesn't use
% eexec encryption and may not even use CharString encryption.
% Define the default font.
/defaultfontname /Ugly def
% Load the font name -> font file name map.
userdict /Fontmap FontDirectory maxlength dict put
/.loadFontmap % <filename>
{ 2 dict begin
mark Fontmap
/;
{ % The stack contains a mark, the dictionary, the font name,
% the file or alias name, and possibly additional information
% about the font.
counttomark 3 sub { pop } repeat .growput
Fontmap
} bind def
3 -1 roll run
end
pop pop % pop the mark and the copy of the dictionary
} bind def
(Fontmap) .loadFontmap
% Ghostscript optionally can load individual CharStrings as they are needed.
% (This is intended primarily for machines with very small memories.)
% This happens if DISKFONTS is true. In this case, we define another
% dictionary parallel to FontDirectory that retains an open file
% for every font loaded.
/FontFileDirectory 10 dict def
% Define an augmented version of .buildfont1 that inserts UnderlinePosition
% and UnderlineThickness entries in FontInfo if they aren't there already.
% (This works around the incorrect assumption, made by many word processors,
% that these entries are present in the built-in fonts.)
/.buildfont1x
{ dup /FontInfo known not
{ dup /FontInfo 2 dict .growput }
if
dup dup /FontInfo get dup dup
/UnderlinePosition known exch /UnderlineThickness known and
{ pop pop % entries already present
}
{ dup length 2 add dict copy
dup /UnderlinePosition known not
{ dup /UnderlinePosition 3 index /FontBBox get
1 get 2 div put % 1/2 the font descent
}
if
dup /UnderlineThickness known not
{ dup /UnderlineThickness 3 index /FontBBox get
dup 3 get exch 1 get sub 20 div put % 1/20 the font height
}
if
1 index /FontInfo get wcheck not { readonly } if
/FontInfo exch put
}
ifelse .buildfont1
} bind def
% Define definefont. This is a procedure built on a set of operators
% that do all the error checking and key insertion.
mark
/.buildfont0 where { pop 0 /.buildfont0 load } if
/.buildfont1 where { pop 1 /.buildfont1x load } if
/.buildfont3 where { pop 3 /.buildfont3 load } if
.dicttomark /.buildfontdict exch def
/definefont
{ 1 dict begin count /d exch def % save stack depth in case of error
{ % Check for disabled platform fonts.
NOPLATFONTS
{ dup maxlength 1 index length sub 2 lt { dup .growdict } if
dup /ExactSize 0 put
}
{ % Hack: if the Encoding looks like it might be the
% Symbol or Dingbats encoding, load those now (for the
% benefit of platform font matching) just in case
% the font didn't actually reference them.
dup /Encoding get length 65 ge
{ dup /Encoding get 64 get
dup /congruent eq { SymbolEncoding pop } if
/a9 eq { DingbatsEncoding pop } if
}
if
}
ifelse
dup /FontType get //.buildfontdict exch get exec
DISKFONTS
{ FontFileDirectory 2 index known
{ dup /FontFile FontFileDirectory 4 index get .growput
}
if
}
if
readonly
}
stopped
{ count d sub { pop } repeat end /invalidfont signalerror }
{ end dup FontDirectory 4 2 roll .growput }
ifelse
} odef
% Ghostscript optionally can load individual CharStrings as they are needed.
% (This is intended primarily for machines with very small memories.)
% Initially, the character definition is the file position of the definition;
% this gets replaced with the actual CharString.
% Note that if we are loading characters lazily, CharStrings is writable.
% _Cstring must be long enough to hold the longest CharString for
% a character defined using seac. This is lenIV + 4 * 5 (for the operands
% of sbw, assuming div is not used) + 2 (for sbw) + 3 * 5 (for the operands
% of seac other than the character codes) + 2 * 2 (for the character codes)
% + 2 (for seac), i.e., lenIV + 43.
/_Cstring 60 string def
% When we initially load the font, we call
% <index|charname> <length> <readproc> cskip_C
% to skip over each character definition and return the file position instead.
% This substitutes for the procedure
% <index|charname> <length> string currentfile exch read[hex]string pop
% [encrypt]
% What we actually store is fileposition * 1000 + length,
% negated if the string is stored in binary form.
% Older fonts use skip_C rather than cskip_C.
% skip_C takes /readstring or /readhexstring as its third argument,
% instead of the entire reading procedure.
/skipproc_C {string currentfile exch readstring pop} cvlit def
/skip_C
{ //skipproc_C dup 3 4 -1 roll put cvx readonly cskip_C
} bind def
/cskip_C
{ exch dup 1000 ge 3 index type /nametype ne or
{ % This is a Subrs string, or the string is so long we can't represent
% its length. Load it now.
exch exec
}
{ % Record the position and length, and skip the string.
dup currentfile fileposition 1000 mul add
2 index 3 get /readstring cvx eq { neg } if
3 1 roll
dup _Cstring length idiv
{ currentfile _Cstring 3 index 3 get exec pop pop
} repeat
_Cstring length mod _Cstring exch 0 exch getinterval
currentfile exch 3 -1 roll 3 get exec pop pop
}
ifelse
} bind def
% Type1BuildGlyph calls load_C to actually load the character definition.
/load_C % <charname> <fileposandlength> -> -
{ dup abs 1000 idiv FontFile exch setfileposition
CharStrings 3 1 roll
dup 0 lt
{ neg 1000 mod string FontFile exch readstring }
{ 1000 mod string FontFile exch readhexstring }
ifelse pop
% If the CharStrings aren't encrypted on the file, encrypt now.
Private /-| get 0 get
dup type /nametype ne { dup length 5 sub 5 exch getinterval exec } { pop } ifelse
dup 4 1 roll put
% If the character is defined with seac, load its components now.
mark exch seac_C
counttomark
{ StandardEncoding exch get dup CharStrings exch get
dup type /integertype eq { load_C } { pop pop } ifelse
} repeat
pop % the mark
} bind def
/seac_C % charstring -> achar bchar ..or nothing..
{ dup length _Cstring length le
{ 4330 exch _Cstring .type1decrypt exch pop
dup dup length 2 sub 2 getinterval <0c06> eq % seac
{ dup length
Private /lenIV known { Private /lenIV get } { 4 } ifelse
exch 1 index sub getinterval
% Parse the string just enough to extract the seac information.
% We assume that the only possible operators are hsbw, sbw, and seac,
% and that there are no 5-byte numbers.
mark 0 3 -1 roll
{ exch
{ { dup 32 lt
{ pop 0 }
{ dup 247 lt
{ 139 sub 0 }
{ dup 251 lt
{ 247 sub 256 mul 108 add 1 1 }
{ 251 sub -256 mul -108 add -1 1 }
ifelse
}
ifelse
}
ifelse
} % 0
{ mul add 0 } % 1
}
exch get exec
}
forall pop
counttomark 1 add 2 roll cleartomark % pop all but achar bchar
}
{ pop % not seac
}
ifelse
}
{ pop % punt
}
ifelse
} bind def
% Define an auxiliary procedure for loading a font.
% If DISKFONTS is true and the body of the font is not encrypted with eexec:
% - Prevent the CharStrings from being made read-only.
% - Substitute a different CharString-reading procedure.
% (eexec disables this because the implicit 'systemdict begin' hides
% the redefinitions that make the scheme work.)
% We assume that:
% - The magic procedures (-|, -!, |-, and |) are defined with
% executeonly or readonly;
% - The contents of the reading procedures are as defined in bdftops.ps;
% - The font ends with
% <font> <Private> <CharStrings>
% readonly put noaccess|readonly put
4 dict begin
/dict % leave room for FontFile
{ 1 add dict
} bind def
/executeonly % for reading procedures
{ readonly
} def
/noaccess % for Subrs strings and Private dictionary
{ readonly
} def
/readonly % for procedures and CharStrings dictionary
{ % We want to take the following non-standard actions here:
% - If the operand is the CharStrings dictionary, do nothing;
% - If the operand is a number (a file position replacing the
% actual CharString), do nothing;
% - If the operand is either of the reading procedures (-| or -!),
% substitute a different one.
dup type /dicttype eq % CharStrings or Private
{ 1 index /CharStrings ne { readonly } if }
{ dup type /arraytype eq % procedure or data array
{ dup length 5 ge 1 index xcheck and
{ dup 0 get /string eq
1 index 1 get /currentfile eq and
1 index 2 get /exch eq and
1 index 3 get dup /readstring eq exch /readhexstring eq or and
1 index 4 get /pop eq and
{ /cskip_C cvx 2 packedarray cvx
}
{ readonly
}
ifelse
}
{ readonly
}
ifelse
}
{ dup type /stringtype eq % must be a Subr string
{ readonly }
if
}
ifelse
}
ifelse
} bind def
currentdict end readonly /.loadfontdict exch def
/.loadfont % <file> .loadfont ->
{ mark exch systemdict begin
DISKFONTS { .loadfontdict begin } if
% We really would just like systemdict on the stack,
% but fonts produced by Fontographer require a writable dictionary....
8 dict begin % garbage
% We can't just use `run', because we want to check for
% .PFB files. We can't save the packing status anywhere,
% so we need two separate control paths.
% Also, we would like to use `false /PFBDecode filter',
% but this occasionally produces a whitespace character as
% the first of an eexec section, so we can't do it.
% Finally, since the interpreter doesn't currently automatically
% close an input file when the file reaches EOF (unless it's
% the interpreter's current input file), we must explicitly
% close the real file if we used a PFB filter.
currentpacking
{ false setpacking
{ dup read not { -1 } if
2 copy unread 16#80 eq
{ dup true /PFBDecode filter cvx exec closefile }
{ cvx exec }
ifelse
} stopped % split up `execute'
true setpacking
$error /newerror get and {handleerror} if
}
{ { dup read not { -1 } if
2 copy unread 16#80 eq
{ dup true /PFBDecode filter cvx exec closefile }
{ cvx exec }
ifelse
} execute
}
ifelse
DISKFONTS { end } if
end end cleartomark
} bind def
% Define a procedure for defining aliased fonts.
% We just copy the original font, changing the FontName.
/.aliasfont % <name> <font> -> <newFont>
{ dup length 2 add dict
dup 3 -1 roll { 1 index /FID eq { pop pop } { put dup } ifelse } forall
/FontName 3 index put
definefont
} odef % bind def
% Define findfont so it tries to load a font if it's not found.
/findfont
{ % Since PostScript has no concept of goto, or even blocks with
% exits, we use a loop as a way to get an exitable scope.
% The loop is never executed more than twice.
{
dup FontDirectory exch known % Already loaded?
{ FontDirectory exch get exit }
if
dup Fontmap exch known not % Unknown font name.
{ dup defaultfontname eq
{ (Default font ) print cvx =only
( not found in Fontmap! Giving up.\n) print flush
1 .quit
} if
QUIET not
{ (Substituting ) print defaultfontname cvx =only
( for unknown font ) print dup == flush
} if
defaultfontname findfont .aliasfont exit
}
if
dup Fontmap exch get
% Check for a font alias.
dup type /nametype eq
{ findfont .aliasfont exit
}
if
% If we can't open the file, substitute for the font.
findlibfile
{ % Stack: fontname fontfilename fontfile
DISKFONTS
{ 1 index (r) file
FontFileDirectory exch 4 index exch .growput
}
if
QUIET not
{ (Loading ) print 2 index =only
( font from ) print exch print (... ) print flush }
{ exch pop }
ifelse
.loadfont
QUIET not
{ vmstatus 3 { =only ( ) print } repeat
(done.\n) print flush
} if
% Check to make sure the font was actually loaded.
dup FontDirectory exch known { findfont exit } if
(Loading ) print dup cvx =only
( font failed, substituting ) print defaultfontname cvx =only
(.\n) print flush
defaultfontname findfont .aliasfont exit
}
if
% findlibfile failed, substitute the default font.
% Stack: fontname fontfilename
(Can't find \(or can't open\) font file ) print print
dup defaultfontname eq
{ ( for default font \() print cvx =only
(\)! Giving up.\n) print flush 1 .quit
}
{ ( for font ) print dup cvx =only
(, substituting ) print defaultfontname cvx =only
(.\n) print flush
defaultfontname findfont .aliasfont
}
ifelse
exit
} loop % end of loop
} odef % bind def
% The CharStrings are a dictionary in which the key is the character name,
% and the value is a compressed and encrypted representation of a path.
% For detailed information, see the book "Adobe Type 1 Font Format",
% published by Adobe Systems Inc.
% Here are the BuildChar and BuildGlyph implementation for Type 1 fonts.
% The names Type1BuildChar and Type1BuildGlyph are known to the interpreter.
/Type1BuildChar
{ 1 index /Encoding get exch get Type1BuildGlyph
} bind def
/Type1BuildGlyph
{ exch begin
dup CharStrings exch .knownget not
{ QUIET not
{ (Substituting .notdef for ) print = flush
} { pop } ifelse
/.notdef CharStrings /.notdef get
} if
% stack: charname charstring
PaintType 0 ne
{ 1 setmiterlimit 1 setlinejoin 1 setlinecap
currentdict /StrokeWidth .knownget not { 0 } if
setlinewidth
} if
dup type /stringtype eq % encoded outline
{ outline_C
}
{ dup type /integertype eq % file position for lazy loading
{ 1 index exch load_C dup CharStrings exch get outline_C
}
{ % PostScript procedure
currentdict end systemdict begin begin exec end
}
ifelse
}
ifelse
end
} bind def
% Make the call on setcachedevice a separate procedure,
% so we can redefine it if the composite font extensions are present.
% (We don't use the obvious
% /setcachedevice_C /setcachedevice load def
% because that would bind it into outline_C.)
/setcachedevice_C { setcachedevice } bind def
/outline_C % <charname> <charstring> -> -
{ currentdict /Metrics .knownget
{ 2 index .knownget
{ dup type dup /integertype eq exch /realtype eq or
{ % <wx>
exch .type1addpath 0
}
{ dup length 2 eq
{ % [<wx> <sbx>]
exch 1 index 0 get 0 .type1addpath
1 get 0
}
{ % [<wx> <wy> <sbx> <sby>]
aload pop 5 -1 roll 3 1 roll .type1addpath
}
ifelse
}
ifelse
}
{ .type1addpath currentpoint
}
ifelse
}
{ .type1addpath currentpoint
}
ifelse % stack: wx wy
pathbbox
PaintType 0 ne
{ % Expand the bounding box by the stroke width.
% (Actually, only half the stroke width is needed.)
4 -1 roll currentlinewidth sub
4 -1 roll currentlinewidth sub
4 -1 roll currentlinewidth add
4 -1 roll currentlinewidth add
}
if
setcachedevice_C
PaintType 0 eq { fill } { stroke } ifelse
pop
} bind def
% Find all the precompiled font operators in systemdict.
systemdict
{ exch =string cvs (.font_) anchorsearch
{ pop pop exec % execute the operator, returns the font dictionary
dup begin
Encoding type /stringtype eq
{ Encoding cvn cvx exec /Encoding exch def
}
if
FontName exch
end definefont pop
}
{ pop pop
}
ifelse
}
forall
% Define a procedure to load all known fonts.
% This isn't likely to be very useful.
/loadallfonts
{ Fontmap { pop findfont pop } forall
} bind def